import csv
import hashlib
import json
import os
import time
from django.core.signals import request_started, request_finished
from django.dispatch import receiver
from django.views.decorators.cache import cache_page
from learnDjango import settings
from django.core.mail import send_mail
from django.core.paginator import Paginator
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import auth
from django import forms
from django.views.decorators.csrf import csrf_exempt
from learnDjango.forms import UserModelForm
from learnDjango.signal import register_signal
from zxy.models import Book, PubName, UserInfo, detection


# 用户的登录逻辑处理
@csrf_exempt
def login_view(request):
    # 处理GET请求
    if request.method == 'GET':
        # 1, 首先检查session，判断用户是否第一次登录，如果不是，则直接重定向到首页
        if 'username' in request.session:  # request.session 类字典对象
            return HttpResponseRedirect('/all_book')
        # 2, 然后检查cookie，是否保存了用户登录信息
        if 'username' in request.COOKIES:
            # 若存在则赋值回session，并重定向到首页
            request.session['username'] = request.COOKIES['username']
            return HttpResponseRedirect('/all_book')
        # 不存在则重定向登录页，让用户登录
        return render(request, 'login.html')
    # 处理POST请求
    elif request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        m = hashlib.md5()
        m.update(password.encode())
        password_m = m.hexdigest()
        # 判断输入是否其中一项为空或者格式不正确
        if not username or not password:
            error = '你输入的用户名或者密码错误!'
            return render(request, 'login.html', locals())
        # 若输入没有问题则进入数据比对阶段，看看已经注册的用户中是否存在该用户
        user = auth.authenticate(request, username=username, password=password)
        # 由于使用了filter, 所以返回值user是一个数组，但是也要考虑其为空的状态，即没有查到该用户
        if not user:
            error = '用户不存在或用户密码输入错误!'
            return render(request, 'login.html', locals())
        # 登录
        auth.login(request, user)
        request.session['username'] = username
        response = HttpResponseRedirect('/all_book')
        # 检查post 提交的所有键中是否存在 isSaved 键
        if 'isSaved' in request.POST.keys():
            # 若存在则说明用户选择了记住用户名功能，执行以下语句设置cookie的过期时间
            response.set_cookie('username', username, 60 * 60 * 24 * 7)
        return response


# 实现退出功能
def logout_view(request):
    # 删除session
    if 'username' in request.session:
        del request.session['username']
    resp = HttpResponseRedirect('/login')
    # 删除cookie
    if 'username' in request.COOKIES:
        resp.delete_cookie('username')
    auth.logout(request)
    return resp


# 搜索书籍界面
def search_title_form(request):
    return render(request, 'search_title.html')


# 显示搜索到的书籍界面
def search_title(request):
    if not request.GET.get('title'):
        errors = '搜索内容不能为空'
        return render(request, 'search_title.html', locals())
    title = Book.objects.filter(title__icontains=request.GET.get('title'))
    return render(request, 'book_list.html', locals())


# 显示全部书籍
def all_book(request):
    try:
        all_books = Book.objects.all().order_by('price')
        if not all_books:
            return HttpResponse('书籍信息表为空，请录入！' +
                                '<p><a href="/add_book/">添加书籍</a></p>')
    except Exception as e:
        print(e)
    return render(request, 'all_book.html', locals())


# 添加书籍
@csrf_exempt
def add_book(request):
    if request.method == 'GET':
        return render(request, 'add_book.html')
    elif request.method == 'POST':
        title = request.POST.get('title')
        price = request.POST.get('price')
        retail_price = float(request.POST.get('retail_price'))
        pub = request.POST.get('pub')
        pub_name = PubName.objects.get(pubname=str(pub))

        # 判断书籍是否存在
        old_book = Book.objects.filter(title=title)
        if old_book:
            return HttpResponse('您添加的书籍已存在！')

        Book.objects.create(title=title, price=price, retail_price=retail_price, pub=pub_name)

        return HttpResponseRedirect('/all_book')
    return HttpResponse('请输入正确的Http请求方法！')


# 更新书籍
@csrf_exempt
def update_book(request, book_id):
    book = Book.objects.get(id=book_id)
    if request.method == 'GET':
        return render(request, 'update_book.html', locals())
    elif request.method == 'POST':
        price = request.POST.get('price')
        retail_price = request.POST.get('retail_price')
        book.price = price
        book.retail_price = retail_price
        book.save()
        return HttpResponseRedirect('/all_book')
    return HttpResponse('书籍信息更新功能')


# 删除书籍
@csrf_exempt
def delete_book(request, book_id):
    book = Book.objects.get(id=book_id)
    book.delete()
    return HttpResponseRedirect('/all_book')


# views.py编写
@csrf_exempt
def user_add_form(request):
    if request.method == "POST":
        user = UserModelForm(request.POST)
        if user.is_valid():
            user = UserInfo.objects.create(username=user.cleaned_data['username'],
                                           password=user.cleaned_data["password"],
                                           gender=user.cleaned_data['gender'])
            # user_add.html只需要接收变量{{ user }}即可
            return render(request, 'user_add.html', locals())
        else:
            return render(request, 'useradd_model_form.html', context={'form': user})
    else:
        return render(request, 'useradd_model_form.html', {'form': UserModelForm()})


# 测试分页功能
def page_test(request):
    books = Book.objects.all()
    paginator = Paginator(books, 2)
    num_p = request.GET.get('page', 1)  # 以page为键得到默认的页面1
    page = paginator.page(int(num_p))
    return render(request, 'page_test.html', locals())


# 发邮件
def send_email(request):
    subject = 'C语言中文网链接'  # 主题
    from_email = settings.EMAIL_FROM  # 发件人，在settings.py中已经配置
    to_email = '1721993707@qq.com'  # 邮件接收者列表
    # 发送的消息
    message = 'c语言中文网欢迎你点击登录 http://c.biancheng.net/'  # 发送普通的消息使用的时候message
    # meg_html = '<a href="http://www.baidu.com">点击跳转</a>'  # 发送的是一个html消息 需要指定
    send_mail(subject, message, from_email, [to_email])
    return HttpResponse('OK,邮件已经发送成功!')


# 上传文件
def upload(request):
    if request.method == 'GET':
        return render(request, 'upload.html')
    elif request.method == 'POST':
        # 使用request.FILES['myfile']获得文件流对象file
        files = request.FILES.getlist('myfiles')
        for file in files:
            # 文件储存路径，应用settings中的配置，file.name获取文件名
            filename = os.path.join(settings.MEDIA_ROOT, file.name)
            # 写文件
            with open(filename, 'wb') as f:
                # file.file 获取文件字节流数据
                data = file.file.read()
                f.write(data)
        return HttpResponse('成功保存了 %d 个文件' % len(files))


# 生成csv文本导出
def test_csv(request):
    # 生成csv文本
    # 生成response的content-type头
    res = HttpResponse(content_type='text/csv')
    res.charset = 'utf-8-sig'
    # 固定格式,添加 content-Disposition头，设置以附件方式下载，并给文件添加默认文件名
    res['Content-Disposition'] = 'attachment;filename="allBook.csv"'
    # 获取数据库中数据
    books = Book.objects.all()
    # 生成writer的写对象
    writer = csv.writer(res)
    # 写csv表头，即想要展示字段名
    writer.writerow(['id', 'title', 'price', 'retail_price', 'public'])
    # 写具体数据
    for book in books:
        writer.writerow([book.id, book.title, book.price, book.retail_price, book.pub.pubname])
    return res


# 在缓存有效时间内不会阻塞，直到缓存过期重新阻塞3秒
@cache_page(60)  # 缓存有效时间60s
def test_cache(request):
    t1 = time.time()  # 得到当前时间戳
    time.sleep(3)  # 阻塞三秒
    html = 't1 is %s' % t1
    return HttpResponse(html)


'''
# 信号
@receiver(request_started)
def request_started_callback(sender, **kwargs):
    print("请求开始：%s" % kwargs['environ'])


@receiver(request_finished)
def request_finished_callback(sender, **kwargs):
    print("请求完成")
'''


def hello_my_signal(request):
    # 注意要和回调函数中的**kwargs的参数保持一致
    # 参数 sender（信号发送者指函数） **named（**kwargs参数相同）
    register_signal.send(hello_my_signal, request=request, user=UserInfo.objects.get(username="zxy"))
    print("注册成功已经发送邮件")
    return HttpResponse('Hello signal')


def ids(request):
    if request.method == 'POST':
        data = json.loads(request.body.decode())
        # print(data['src_ip']+":"+data['src_port'], data['dst_ip']+":"+data['dst_port'], data['label'])
        src_ip = data['src_ip']
        src_port = data['src_port']
        dst_ip = data['dst_ip']
        dst_port = data['dst_port']
        label = data['label']

        detection.objects.create(src_ip=src_ip, src_port=src_port, dst_ip=dst_ip, dst_port=dst_port, label=label)

        return render(request, 'ids.html', locals())
    else:
        return HttpResponse('Hello')


def school(request):
    return render(request, 'school.html')
